package com.hx.thread.reentrant;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author Minghua Chen
 * @date 2020-09-02 22:30
 * 描述: 读写锁
 */
public class ReadWriteLockDemo {
    private static final Logger logger = LoggerFactory.getLogger(ReadWriteLockDemo.class);

    public static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(false);
    public static final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
    public static final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();

    public static void main(String[] args) {
        ReadWriteLockDemo instance = new ReadWriteLockDemo();
        Thread t1 = new Thread(instance::write);
        Thread t2 = new Thread(instance::read);
        Thread t3 = new Thread(instance::read);
        Thread t4 = new Thread(instance::write);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        /**
         [Thread-0] INFO com.hx.thread.reentrant.ReadWriteLockDemo - 获取写锁
         [Thread-0] INFO com.hx.thread.reentrant.ReadWriteLockDemo - ---写---
         [Thread-0] INFO com.hx.thread.reentrant.ReadWriteLockDemo - 释放写锁
         [Thread-1] INFO com.hx.thread.reentrant.ReadWriteLockDemo - 获取读锁
         [Thread-1] INFO com.hx.thread.reentrant.ReadWriteLockDemo - ---读---
         [Thread-2] INFO com.hx.thread.reentrant.ReadWriteLockDemo - 获取读锁
         [Thread-2] INFO com.hx.thread.reentrant.ReadWriteLockDemo - ---读---
         [Thread-1] INFO com.hx.thread.reentrant.ReadWriteLockDemo - 释放读锁
         [Thread-3] INFO com.hx.thread.reentrant.ReadWriteLockDemo - 获取写锁
         [Thread-2] INFO com.hx.thread.reentrant.ReadWriteLockDemo - 释放读锁
         [Thread-3] INFO com.hx.thread.reentrant.ReadWriteLockDemo - ---写---
         [Thread-3] INFO com.hx.thread.reentrant.ReadWriteLockDemo - 释放写锁
         */
    }

    /**
     * 写
     */
    public void write() {
        writeLock.lock();
        try {
            logger.info("获取写锁");
            logger.info("---写---");
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
            logger.info("释放写锁");
        }
    }

    /**
     * 读取
     */
    public void read() {
        readLock.lock();
        try {
            logger.info("获取读锁");
            logger.info("---读---");
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();
            logger.info("释放读锁");
        }
    }
}
